/*******************************************************************************
 * Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
 * Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 *******************************************************************************/
package com.qinyeit.configuration;

import com.qinyetech.springstage.core.repository.jdbc.PageNamedParameterJdbcTemplate;
import lombok.Data;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * <p>ClassName: com.qinyeit.configuration.BranchDataSourceConfiguration
 * <p>Function: 分公司数据库配置
 * <p>date: 2018-11-21 19:25
 *
 * @author wuqing
 * @version 1.0
 * @since JDK 1.8
 */
@Configuration
@EnableTransactionManagement
public class DataSourceConfiguration {
    @Bean(name="branchJdbcTemplate")
    public PageNamedParameterJdbcTemplate jdbcTemplate(@Qualifier("branchDataSource") DataSource dataSource){
        return new PageNamedParameterJdbcTemplate(dataSource);
    }

    @Bean(name = "primaryDataSource")
    @Primary
    public DataSource primaryDataSource(@Qualifier("primaryDataSourceConfig") AtomikosDataSourceProperties config) {
        return buildAtomikosDataSourceBean(buildDataSourceProperty(config),config.getName());
    }

    @Bean(name = "branchDataSource")
    public DataSource branchDataSource(@Qualifier("branchDataSourceConfig") AtomikosDataSourceProperties config) {
        return buildAtomikosDataSourceBean(buildDataSourceProperty(config),config.getName());
    }

    @Bean(name="primaryDataSourceConfig")
    @ConfigurationProperties("spring.datasource.primary")
    public AtomikosDataSourceProperties primaryDataSourceProperty(){
        return new AtomikosDataSourceProperties();
    }
    @Bean(name="branchDataSourceConfig")
    @ConfigurationProperties("spring.datasource.branch")
    public AtomikosDataSourceProperties branchDataSourceProperty(){
        return new AtomikosDataSourceProperties();
    }


    private AtomikosDataSourceBean buildAtomikosDataSourceBean(Properties properties, String name){
        AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
        ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
        ds.setUniqueResourceName(name);
        ds.setPoolSize(5);
        ds.setXaProperties(properties);
        return ds;
    }
    private Properties buildDataSourceProperty(AtomikosDataSourceProperties atomikosDataSourceProperties){
        Properties prop = new Properties();
        prop.put("url", atomikosDataSourceProperties.getUrl());
        prop.put("username",atomikosDataSourceProperties.getUsername());
        prop.put("password", atomikosDataSourceProperties.getPassword());
        prop.put("driverClassName",atomikosDataSourceProperties.getDriverClassName());
        prop.put("initialSize",atomikosDataSourceProperties.getInitialSize());
        prop.put("maxActive",atomikosDataSourceProperties.getMaxActive());
        prop.put("minIdle", atomikosDataSourceProperties.getMinIdle());
        prop.put("maxWait", atomikosDataSourceProperties.getMaxWait());
        prop.put("poolPreparedStatements", atomikosDataSourceProperties.getPoolPreparedStatements());

        prop.put("maxPoolPreparedStatementPerConnectionSize",
                atomikosDataSourceProperties.getMaxPoolPreparedStatementPerConnectionSize());

        prop.put("validationQuery", atomikosDataSourceProperties.getValidationQuery());
        prop.put("testOnBorrow", atomikosDataSourceProperties.getTestOnBorrow());
        prop.put("testOnReturn",atomikosDataSourceProperties.getTestOnReturn());
        prop.put("testWhileIdle",atomikosDataSourceProperties.getTestWhileIdle());
        prop.put("timeBetweenEvictionRunsMillis",
                atomikosDataSourceProperties.getTimeBetweenEvictionRunsMillis());
        prop.put("minEvictableIdleTimeMillis", atomikosDataSourceProperties.getMinEvictableIdleTimeMillis());
        return prop;
    }
    @Data
    class AtomikosDataSourceProperties{
        private String name="";
        private String url="";
        private String username="";
        private String password="";
        private String driverClassName="";
        private Integer initialSize;
        private Integer maxActive;
        private Integer minIdle;
        private Long  maxWait;
        private Boolean poolPreparedStatements=true;
        private Integer maxPoolPreparedStatementPerConnectionSize;
        private String validationQuery="SELECT 'x'";
        private Boolean testOnBorrow=false;
        private Boolean testOnReturn=false;
        private Boolean testWhileIdle=true;
        private Long timeBetweenEvictionRunsMillis;
        private Long minEvictableIdleTimeMillis;

    }
}

